const MsgDecoder = {
  get error() { return -1; }, // 出现错误
  get initDecoder() { return 0 }, // 解码器已初始化 尽可能与下载文件一致.减少写数据

  get uninitDecoder() { return -10002 }, // 解码器已卸载
  get openDecoder() { return -10003 }, // 打开解码器
  get closeDecoder() { return -10004 }, // 关闭解码器
  get startDecoding() { return -10005 }, // 解码操作
  get audioCallback() { return -10006 }, // 音频数据
  get videoCallback() { return -10007 }, // 视频数据
  get requestCallback() { return -10008 }, // 请求数据
  get seekTo() { return -10009 }, // 跳转时间
  get sendData() { return -10010 }, // 发送数据
  get simpleDecode() { return -10011 }, // 简易解码 包含初始化等一键式解码
  get testApi() { return -10012 }, // 
  get offsetTime() { return -10013 }, // 
  get decoderOnePacket() { return -10014 }, // 
  get decoderPack() { return -10015 }, // 
  get initVideo() { return -10016 }, // 
  get created() { return -10017 }, // 
  get reload() { return -10018 }, // 
  get continue() { return -10019 }, // 
  get pause() { return -10020 }, // 
  get setOffsetTime() { return -10021 }, // 
  get fileIn() { return -10022 }, // 解码器已卸载
};

// var rel = 0;
function loaderLib() {
  try {
    if (typeof SharedArrayBuffer == "undefined") {
      self.importScripts("libn.js");
    } else {
      self.importScripts("libt.js");
    }
  } catch (error) {
    if (typeof SharedArrayBuffer != "undefined") {
      try {
        self.importScripts("libn.js");
      } catch (error) {
        console.log('搜狗重载');
        console.log(error);
        self.postMessage({ e: MsgDecoder.reload });
        // setTimeout(loaderLib, 10);
        self.close();
      }
    } else {
      console.log('重载');
      console.log(error);
      self.postMessage({ e: MsgDecoder.reload });
      // setTimeout(loaderLib, 10);
      self.close();
    }
    return;
  }
}
loaderLib();
// self.importScripts("libffmpeg.js");

Module.onRuntimeInitialized = function () {
  if (self.decoder) {
    self.decoder.onWasmLoaded();
  } else {
    console.error("解码器加载失败!");
  }
}

function Decoder() {
  this.accurateSeek = true;
  this.wasmLoaded = false;
  this.tmpReqQue = [];
  this.cacheBuffer = null;
  this.cacheBufferSize = 0;
  this.decodeTimer = null;
  this.videoCallback = null;
  this.audioCallback = null;
  this.requestCallback = null;
  this.offsetTime = 0;
  this.decoderOnePacketRet = {};

  this.run = 0;
  setInterval(this.decoderVideo.bind(this), 1);
}

Decoder.prototype.decoderVideo = function () {
  // console.log(this.run);
  if (this.run) {
    if (Module._decodeOnePacket()) {
      this.run = 0;
      self.postMessage({ e: MsgDecoder.continue });
      if (this.retData) self.postMessage(this.retData);
      delete this.retData;
      delete this.post;
    }
    if (this.post) {
      self.postMessage(this.post);
      delete this.post;
    }
  } else if (this.post) {
    self.postMessage(this.post);
    delete this.post;
  }
}
Decoder.prototype.decoderPack = function (data) {
  this.run = 0;
  let init = data.init;

  if (!this.initEd || init) {
    if (!init) data.init = { fileSize: 0, listLen: 0 };
    this.initEd = !Module._initDecoder(data.init.fileSize, data.init.listLen, this.videoCallback, this.audioCallback, this.requestCallback);
  }

  if (data.d.length > this.cacheBufferSize) {
    this.cacheBufferSize = data.d.length;
    if (this.cacheBuffer) Module._free(this.cacheBuffer);
    this.cacheBuffer = Module._malloc(this.cacheBufferSize);
  }
  data.init = data.init ? 1 : 0;
  data.init = data.init | (1 << 1); // 清除上一个文件信息.ts片段需要,整片关闭
  if (data.da) data.init = data.init | (1 << 2); // 解码音频
  Module.HEAPU8.set(data.d, this.cacheBuffer);
  let t = new Date();
  try {
    Module._simpleDecode(
      this.cacheBuffer,
      data.d.length,
      data.init,
      parseInt(data.offsetTime) | 0
    );
    if (init) {
      data.init = init;
    } else {
      delete data.init;
    }
  } catch (error) {
    self.postMessage({ e: MsgDecoder.reload, param: data }, [data.d.buffer]); // 重载
    console.log('解码器错误,重载', error);
    self.close();
    return;
  }
  delete data.d;
  data.real = false;
  self.postMessage(data); // 发送开始解码信号

  data.real = true;
  // self.postMessage(data); // 发送开始解码信号
  // self.close();
  this.retData = data;
}


Decoder.prototype.seekTo = function (d) {
  Module._setOffsetTime(d.offsetTime | 0, d.da | 0);
  self.postMessage(d);
};

Decoder.prototype.testApi = function (params) {
  if (this.testApiHandle) {
    clearInterval(this.testApiHandle);
  }
  this.testApiHandle = setInterval(() => {
    Module._testApi(params.a, params.b);
  }, 100);
  return { a: params.a, b: params.b };
}
Decoder.prototype.onmessage = function (evt) {
  // console.log(evt.data);
  switch (evt.data.e) {
    case MsgDecoder.seekTo:
      this.seekTo(evt.data);
      break;
    case MsgDecoder.decoderPack:
      this.decoderPack(evt.data);
      break;
    case MsgDecoder.continue:
      // console.log("继续", this.run);
      if (this.run) {
        self.postMessage(evt.data);
      } else {
        this.run = 1;
        this.post = evt.data;
      }
      break;
    case MsgDecoder.pause:
      // console.log("暂停", this.run);
      if (this.run) {
        this.post = evt.data;
        this.run = 0;
      } else {
        self.postMessage(evt.data);
      }
      break;
    case MsgDecoder.testApi:
      this.testApi(evt.data);
      break;
    default:
      console.warn("解码器", evt.data);
  }
}
Decoder.prototype.onWasmLoaded = function () {
  this.wasmLoaded = true;
  this.videoCallback = Module.addFunction(function (buff, size, timestamp) {
    let objData = {};
    try {
      objData = {
        e: MsgDecoder.videoCallback,
        s: timestamp,
        d: new Uint8Array(Module.HEAPU8.subarray(buff, buff + size))
      };
    } catch (error) {
      console.log(error);
      // console.log(buff, size, timestamp);
      self.postMessage({ e: MsgDecoder.reload });
      // setTimeout(loaderLib, 10);
      self.close();
      return;
    }
    self.postMessage(objData, [objData.d.buffer]);
    delete objData;
    return;
  }, 'viid');
  this.audioCallback = Module.addFunction(function (buff, size, timestamp) {
    let objData = {
      e: MsgDecoder.audioCallback,
      s: timestamp,
      d: new Uint8Array(Module.HEAPU8.subarray(buff, buff + size)),
    };
    self.postMessage(objData, [objData.d.buffer]);
  }, 'viid');
  this.requestCallback = Module.addFunction(function (q, i) {
    let t, n, o;
    if (q < 0) {
      switch (q) {
        case -1: // 初始化信息回执
          n = i >> 2;
          t = Module.HEAP32.subarray(n, n + 9);
          n = new DataView(new ArrayBuffer(4));
          n.setInt32(0, t[8]);
          o = {
            e: MsgDecoder.initVideo,
            v: { d: t[0], p: t[1], w: t[2], h: t[3] },
            a: { f: t[4], c: t[5], r: t[6] },
            id: t[7],
            v0: n.getFloat32(0)
          };
          // console.log(o);
          self.postMessage(o);
          break;
        default:
          break;
      }
    } else if (q > 0) {
      o = {
        e: MsgDecoder.fileIn,
        d: new Uint8Array(Module.HEAPU8.subarray(i, i + q)),
      };
      console.log(o, i, q);
      self.postMessage(o, [o.d.buffer]);
    }
  }, 'iii');
  let _this = this;
  self.onmessage = this.onmessage.bind(this);
  while (this.tmpReqQue.length) {
    self.onmessage({ data: this.tmpReqQue.shift() });
  }
  self.postMessage({ e: MsgDecoder.created }); // 通知主线程,wasm已经加载完毕
};

self.decoder = new Decoder;

self.wasmOnmessage = self.onmessage;
self.onmessage = function (e) {
  if (self.wasmOnmessage && typeof e.data.e == 'undefined') {
    self.wasmOnmessage(e);
  }
  else self.decoder.tmpReqQue.push(e.data);
};


